
#include "Parser.h"
#include <sstream>
#include <stdio.h>
#include <conio.h>
#include <string.h>


Parser::Parser(){
    initialize();
}
Parser::~Parser(){

}

void Parser::initialize(){
        dictionary.insert(make_pair(TELEPORT_COMMAND_STRING,TELEPORT_COMMAND_CODE ));
        dictionary.insert(make_pair(NEWGAME_COMMAND_STRING,NEWGAME_COMMAND_CODE));
        dictionary.insert(make_pair(LOADGAME_COMMAND_STRING,LOADGAME_COMMAND_CODE));
        dictionary.insert(make_pair(RIGHT_COMMAND_STRING,RIGHT_COMMAND_CODE));
        dictionary.insert(make_pair(LEFT_COMMAND_STRING,LEFT_COMMAND_CODE));
        dictionary.insert(make_pair(UP_COMMAND_STRING,UP_COMMAND_CODE));
        dictionary.insert(make_pair(DOWN_COMMAND_STRING,DOWN_COMMAND_CODE));
        dictionary.insert(make_pair(PLOW_COMMAND_STRING,PLOW_COMMAND_CODE));
        dictionary.insert(make_pair(PUT_COMMAND_STRING,PUT_COMMAND_CODE));
        dictionary.insert(make_pair(SLASH_COMMAND_STRING,SLASH_COMMAND_CODE));
        dictionary.insert(make_pair(WATER_COMMAND_STRING,WATER_COMMAND_CODE));
        dictionary.insert(make_pair(HARVEST_COMMAND_STRING,HARVEST_COMMAND_CODE));
        dictionary.insert(make_pair(WAKEUP_COMMAND_STRING,WAKEUP_COMMAND_CODE));
        dictionary.insert(make_pair(SLEEP_COMMAND_STRING,SLEEP_COMMAND_CODE));
        dictionary.insert(make_pair(STATUS_COMMAND_STRING,STATUS_COMMAND_CODE));
        dictionary.insert(make_pair(SAVE_COMMAND_STRING,SAVE_COMMAND_CODE));
        dictionary.insert(make_pair(EXIT_COMMAND_STRING,EXIT_COMMAND_CODE));
        dictionary.insert(make_pair(STORE_COMMAND_STRING,STORE_COMMAND_CODE));
        dictionary.insert(make_pair(BUY_COMMAND_STRING,BUY_COMMAND_CODE));
        dictionary.insert(make_pair(SELL_COMMAND_STRING,SELL_COMMAND_CODE));
		dictionary.insert(make_pair(INVENTORY_COMMAND_STRING,INVENTORY_COMMAND_CODE));
		dictionary.insert(make_pair(PLANT_COMMAND_STRING,PLANT_COMMAND_CODE));
		dictionary.insert(make_pair(EAT_COMMAND_STRING,EAT_COMMAND_CODE));
        dictionary.insert(make_pair(COMMAND_NOT_FOUND_STRING,COMMAND_NOT_FOUND_CODE));
        dictionary.insert(make_pair(ADVENTURE_COMMAND_STRING,ADVENTURE_COMMAND_CODE));
        dictionary.insert(make_pair(COMMAND_COMMAND_STRING,COMMAND_COMMAND_CODE));

        //dictionary.insert(make_pair());
}


CommandToken Parser::createCommandToken (vector< string > tokens){
     vector<string>::iterator vi ; // tokens iterator
     string buff;
     CommandToken commandToken ;
        // tokenisasi
        vi = tokens.begin();
        buff = toLowerCase(*vi);
            CommandDictionary::iterator commandIterator;
            if (dictionary.find(buff) != dictionary.end() ){
                commandToken.command = (dictionary.find(buff))->second;
                // insert parameter
                vi++;
                while (vi != tokens.end()){
                    buff = toLowerCase((*vi));
                    commandToken.stringParam.push_back(buff);
                    vi++;
                }
            } else {
                commandToken.command = COMMAND_NOT_FOUND_CODE;
            }
        //cout << commandToken.command;
    return commandToken;
}

CommandToken Parser::update(){
    //CommandToken commandToken;
    string inputText;
    string buff;
    string str;
    vector<string> tokens;
//	cout << "Breakpoint 2. Getting input.\n" <<endl;

    int a;
    //a = getch();
    //str.clear();
    if (mode== COMMAND_MODE){
        getline(cin, inputText, '#');
        if (inputText.length() != 0){
            stringstream ss(inputText);
            while (ss >> buff){
                tokens.push_back(buff);
			}
            if (tokens.size()== 0){
                tokens.push_back("dummy");
            }
			command.stringParam.clear();
            command = createCommandToken(tokens);
           // processCommand(command); // nanti ditanganin oleh gameState
        }
//	cout << "Breakpoint 3. Returning command.\n" <<endl;
    } else if (mode == ADVENTURE_MODE){
        a = getch();
        if (a== 224){
            a = getch(); //  72, 75, 77, 80 bawah
            if (a == 72){
                tokens.push_back(UP_COMMAND_STRING);
            } else if (a == 75){
                tokens.push_back(LEFT_COMMAND_STRING);
            } else if (a == 77){
                tokens.push_back(RIGHT_COMMAND_STRING);
            }
             else if (a == 80){
                tokens.push_back(DOWN_COMMAND_STRING);
            }
        } else {
            switch (a){
                case 104 : {
                    tokens.push_back(HARVEST_COMMAND_STRING);
                    break;
                }
                case 99 : {
                    tokens.push_back(COMMAND_COMMAND_STRING);
                    break;
                }
                case 112 : {
                    tokens.push_back(PLOW_COMMAND_STRING);
                    break;
                }
                case 119 : {
                    tokens.push_back(WATER_COMMAND_STRING);
                    break;
                }
                case 105 : {
                    tokens.push_back(INVENTORY_COMMAND_STRING);
                    break;
                }
                default :
                    tokens.push_back("dummy");
                break;
            }
        }


        command = createCommandToken(tokens);
    }
	return command;
}


void Parser::update(int key){
    vector<string> tokens;
    if (key == 224){
//        key = getch();
        if (key == 72){
            tokens.push_back (UP_COMMAND_STRING);
        }
        if (tokens.size()== 0){
            tokens.push_back("dummy");
        }
        command = createCommandToken(tokens);
    }

}

CommandToken Parser::getCommand(){
    return command;
}


string	Parser::toString(string token){
	return"";
}
string	Parser::toLowerCase(string token){

    for( unsigned int i=0;i<token.length();i++){
        token[i] = tolower(token[i]);
    }
   return token;//return the converted string
}

